/*
 * Copyright (c) 2020 YuQing <384681@qq.com>
 *
 * This program is free software: you can use, redistribute, and/or modify
 * it under the terms of the Lesser GNU General Public License, version 3
 * or later ("LGPL"), as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the Lesser GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 * *版权所有(c) 2020 YuQing <384681@qq.com>
＊
*本程序是自由软件:您可以使用、再分发和/或修改
*根据较宽松GNU通用公共许可证，版本3的条款
*或更高版本(“LGPL”)，由自由软件基金会发布。
＊
*本程序的发布是希望它会有用，但没有
*任何保证;甚至没有对适销性的默示保证或
*适合某一特定目的。
＊
*您应该已收到较宽松GNU通用公共许可证的副本
*和这个程序一起。如果没有，请参见<https://www.gnu.org/licenses/>。以上翻译结果来自有道神经网络翻译（YNMT）· 通用场景
 * 
 */

//base64.h

#ifndef _BASE64_H
#define _BASE64_H

#include <stdbool.h>

struct base64_context
{
	char line_separator[16];
	int line_sep_len;

	/**
	 * max chars per line, excluding line_separator.  A multiple of 4.	每行最大字符数，不包括line_separator。4的倍数。
	 */
	int line_length;

	/**
	 * letter of the alphabet used to encode binary values 0..63	用于编码二进制值的字母表字母 0..63
	 */
	unsigned char valueToChar[64];

	/**
	 * binary value encoded by a given letter of the alphabet 0..63	给定字母表字母编码的二进制值 0..63
	 */
	int charToValue[256];
	int pad_ch;
};

#ifdef __cplusplus
extern "C" {
#endif

/** use stardand base64 charset		使用标准base64字符集
 */
#define base64_init(context, nLineLength) \
        base64_init_ex(context, nLineLength, '+', '/', '=')


/** stardand base64 encode				标准base64编码
 */
#define base64_encode(context, src, nSrcLen, dest, dest_len) \
        base64_encode_ex(context, src, nSrcLen, dest, dest_len, true)

/** base64 init function, before use base64 function, you should call 		base64初始化函数，在调用base64函数之前，您应该调用
/*
 *  这个函数用于Base64编码。
 *  参数：
 *       context:     Base64上下文。
 *       nLineLength: 一行的长度，如果为0，则不添加行分隔符。
 *       chPlus:      指定用于Base64字符加号(+)的字符。
 *       chSplash:    指定用于Base64字符斜杠(/)的字符。
 *       chPad:       指定用于Base64填充字符等号(=)的字符。
 *  返回值：无。
 */

void base64_init_ex(struct base64_context *context, const int nLineLength, \
		const unsigned char chPlus, const unsigned char chSplash, \
		const unsigned char chPad);

/**
 *  计算源缓冲区编码后的长度。
 *  参数：
 *       context:     Base64上下文。
 *       nSrcLen:     源缓冲区的长度。
 *  返回值：源缓冲区编码后的长度。
 */

int base64_get_encode_length(struct base64_context *context, const int nSrcLen);

/**
 *  对缓冲区进行Base64编码。
 *  参数：
 *       context:   Base64上下文。
 *       src:       源缓冲区。
 *       nSrcLen:   源缓冲区的长度。
 *       dest:      目标缓冲区。
 *       dest_len:  返回目标缓冲区的长度。
 *       bPad:      如果需要填充。
 *  返回值：编码后的缓冲区。
 */

char *base64_encode_ex(struct base64_context *context, const char *src, \
		const int nSrcLen, char *dest, int *dest_len, const bool bPad);

/**
 *  对缓冲区进行Base64解码，仅适用于带有填充的源字符串。
 *  参数：
 *       context:   Base64上下文。
 *       src:       带有填充的源缓冲区。
 *       nSrcLen:   源缓冲区的长度。
 *       dest:       目标缓冲区。
 *       dest_len:   返回目标缓冲区的长度。
 * 返回值：解码后的缓冲区。
 */

char *base64_decode(struct base64_context *context, const char *src, \
		const int nSrcLen, char *dest, int *dest_len);

/**
 *  对缓冲区进行Base64解码，可以处理带有填充或不带填充的源字符串。
 *  参数：
 *       context:   Base64上下文。
 *       src:       带有填充或不带填充的源缓冲区。
 *       nSrcLen:   源缓冲区的长度。
 *       dest:       目标缓冲区。
 *       dest_len:   返回目标缓冲区的长度。
 * 返回值：解码后的缓冲区。
 */

char *base64_decode_auto(struct base64_context *context, const char *src, \
		const int nSrcLen, char *dest, int *dest_len);

/**
 *  设置行分隔符字符串，例如 \n 或 \r\n。
 *  参数：
 *       context:   Base64上下文。
 *       pLineSeparator: 行分隔符字符串。
 * 返回值：无。
 */

void base64_set_line_separator(struct base64_context *context, \
		const char *pLineSeparator);

/**
 *  设置行长度，0表示不添加行分隔符。
 *  参数：
 *       context:   Base64上下文。
 *       length:    行长度。
 * 返回值：无。
 */

void base64_set_line_length(struct base64_context *context, const int length);

#ifdef __cplusplus
}
#endif

#endif

